#ifndef INC_MODEL_MOLECULE_H
#define INC_MODEL_MOLECULE_H

#include <list>
#include <map>
#include <string>

#include "Atom.h"
#include "Fragment.h"
#include "Atom_Element_Indexer.h"

class Atom_Element;
class Molecule_Visitor;
class Atom_Link;

/**
 * FDMDE internal representation of a molecule and its fragment.
 * A fragment is a logical group inside a molecule.
 */
class Molecule
{
private:
    // The list of all the atoms belonging to this molecule
    typedef std::list<Atom*> Atoms;
    Atoms atoms;

	 // The list of all the links between all atoms
    typedef std::list<const Atom_Link*> Atom_Links;
	 Atom_Links atom_links;

    // And a list of all the fragments in this molecule, which in turn have
    // references to the atoms in the above list
    std::vector<Fragment> fragments;

    AtomElementIndexer atom_element_indexer;

public:
    ~Molecule();

    void add(const Atom& at, const Atom_Element& elm);
	 void add_link(const Atom_Link* link);

    /**
     * Notify this molecule that future atoms should be added as part of a new fragment
     */
    void on_fragment_change();

    /**
     * Order atoms by type and then iterate
     */
    void iterate_atoms_by_type(Molecule_Visitor& v) const;
};

#endif /* INC_MODEL_MOLECULE_H */
